#include "types.h"
#include "console.h"
#include "uart.h"
#include "spinlock.h"
#include "ansi.h"

#define CONSOLE_BUFFER_SIZE 128

static struct {
    struct spinlock lock;
    char buffer[CONSOLE_BUFFER_SIZE];
    int count; // 缓冲区中的字符数
    int write_pos; // 下一个写入位置
} console;

void console_init(void) {
    console.count = 0;
    console.write_pos = 0;
    // spinlock_init(&console.lock, "console");
    uart_init();
}

// 将字符放入缓冲区
void console_putc(char c) {
    acquire(&console.lock);

    if (console.count >= CONSOLE_BUFFER_SIZE) {
        // 缓冲区满，强制刷出
        console_flush();
    }

    console.buffer[console.write_pos] = c;
    console.write_pos = (console.write_pos + 1) % CONSOLE_BUFFER_SIZE;
    console.count++;

    // 如果是换行符，也刷出缓冲区
    if (c == '\n') {
        console_flush();
    }

    release(&console.lock);
}

// 强制将缓冲区内容通过UART发送
void console_flush(void) {
    // 注意：这个函数应该在锁的保护下被调用，或者其内部实现需要处理锁
    if (console.count == 0) {
        return;
    }

    int read_pos = (console.write_pos - console.count + CONSOLE_BUFFER_SIZE) % CONSOLE_BUFFER_SIZE;
    for (int i = 0; i < console.count; i++) {
        uart_putc(console.buffer[read_pos]);
        read_pos = (read_pos + 1) % CONSOLE_BUFFER_SIZE;
    }

    console.count = 0;
    console.write_pos = 0; // 可以重置，也可以不重置
}

void console_puts(const char *s) {
    if (!s) return;
    while (*s) {
        console_putc(*s++);
    }
}

void clear_screen(void) {
    // 发送清屏和光标归位的 ANSI 序列
    console_puts(ANSI_CLEAR_SCREEN);
    console_puts(ANSI_CURSOR_HOME);
    // 确保控制字符立即发送到终端
    console_flush();
}
